<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>利用发布订阅模式实现页面布局通信</title>
  </head>
  <style>
    .layout {
      display: flex;
      flex-direction: column;
      height: 800px;
    }
    .layout .header {
      height: 80px;
      background-color: pink;
    }
    .layout .container {
      display: flex;
      flex-direction: row;
      flex: 1;
    }
    .layout .sidebar {
      width: 200px;
      height: 100%;
      background-color: skyblue;
    }
    .layout .content {
      flex: 1;
      background-color: blueviolet;
    }
    .sidebar ul {
      padding: 0;
    }
    .sidebar li {
      margin-bottom: 2px;
      list-style: none;
      height: 30px;
      border: 1px solid;
      text-align: center;
      line-height: 30px;
      cursor: pointer;
    }
  </style>
  <body>
    <div class="layout">
      <header class="header"></header>
      <div class="container">
        <div class="sidebar">
          <ul>
            <li>商品</li>
            <li>人员</li>
            <li>物资</li>
          </ul>
        </div>
        <div class="content"></div>
      </div>
    </div>
  </body>
  <script>
    class PublishSubscribeCenter {
      // 事件频道
      eventChannel = {};

      // 订阅
      subscribe(type, callback) {
        //向事件频道中添加不同类型的事件（同一时间可以订阅多个方法）
        if (this.eventChannel[type]) {
          this.eventChannel[type].push(callback);
        } else {
          this.eventChannel[type] = [callback];
        }
      }

      // 取消订阅
      unsubscribe(type, callback) {
        if (this.eventChannel[type]) {
          if (callback) {
            this.eventChannel[type] = this.eventChannel[type].filter(
              (func) => func !== callback
            );
          } else {
            this.eventChannel[type] = [];
          }
        }
      }

      // 发布事件
      publish(type, data) {
        if (this.eventChannel[type]) {
          const events = this.eventChannel[type];
          events.forEach((callback) => {
            callback(data);
          });
        }
      }
    }

    // 创建订阅发布中心
    const pbc = new PublishSubscribeCenter();

    // 更新 Header
    const updateHeader = function (data) {
      const header = document.querySelector(".header");
      header.innerHTML = data;
    };

    // 更新 content
    const updateContent = function (data) {
      const header = document.querySelector(".content");
      header.innerHTML = data;
    };

    // 给订阅发布中心订阅事件
    pbc.subscribe("updateHeader", updateHeader);
    pbc.subscribe("updateContent", updateContent);

    const sidebarList = document.querySelectorAll(".sidebar li");

    sidebarList.forEach((li) => {
      //给侧边栏的每个项添加事件
      li.addEventListener(
        "click",
        function () {
          // 发布事件
          pbc.publish("updateHeader", li.innerHTML);
          pbc.publish("updateContent", li.innerHTML);
        },
        false
      );
    });
  </script>
</html>
